Unit myGPSThreads;{$M+}{$H+}{$IFDEF FPC}{$MODE delphi}{$ENDIF}

Interface

Uses
	Classes, SysUtils, 
	mnCommClasses, mnCommStreams, mnCommThreads, 
	myGPSUtils;

Type
	TGPSThread = Class(TmnCommThread)
	Private
		FEndOfLine: String;
		FBuffer:	String;
		FGPSInfo:   TGPSInfo;
		Procedure SetWest(WEStr: String);
		Procedure SetEast(WEStr: String);
		Procedure SetKMH(KMHStr: String);
		Procedure SetMS(MSStr: String);
		Procedure SetKM(KMStr: String);
		Procedure SetM(MStr: String);
		Procedure SetSouth(NSStr: String);
		Procedure SetNorth(NSStr: String);
		Procedure SetTimeZone(dTimeZone: Double);
	Protected
		Procedure StringArrived(S: String); Override;
		Procedure Parse(Command: String); Virtual;
	Public
		Constructor Create(CommPort: String; BaudRate: Integer);
		Destructor Destroy; Override;
		Property EndOfLine: String read FEndOfLine write FEndOfLine;
		Function Macro2GPS(GPSMacro: String): String;
		Function PseudoMacro2GPS(GPSMacro: String): String;
		Property KM: String write SetKM;
		Property M: String write SetM;
		Property KMH: String write SetKMH;
		Property MS: String write SetMS;
		Property South: String write SetSouth;
		Property East: String write SetEast;
		Property North: String write SetNorth;
		Property West: String write SetWest;
		Property TimeZone: Double write SetTimeZone;
	End;

Implementation

Constructor TGPSThread.Create(CommPort: String; BaudRate: Integer);
Begin
	CommStream := TmnCommStream.Create(True, CommPort, BaudRate);
	CommStream.ReadTimeout := 10;
	CommStream.ReadTimeoutConst := 100;
	CommStream.ConnectMode := ccmRead;
	CommStream.Connect;
	EndOfLine := #13;
	FreeOnTerminate := True;
	FGPSInfo:=TGPSInfo.Create;
	Inherited Create(True, CommStream);
End;

Destructor TGPSThread.Destroy;
Begin
	FreeAndNil(FGPSInfo);
	Inherited Destroy;
End;

Procedure TGPSThread.StringArrived(S: String);
Var
	P: Integer;
Begin
	FBuffer := FBuffer + S;
	P := AnsiPos(FEndOfLine, FBuffer);
	While P > 0 Do
	Begin
		Parse(Copy(FBuffer, 1, P - 1));
		FBuffer := Copy(FBuffer, P + 1, MaxInt);
		P := AnsiPos(FEndOfLine, FBuffer);
	End;
End;

Procedure TGPSThread.Parse(Command: String);
Begin
	FGPSInfo.Parse(Command);
End;

Function TGPSThread.Macro2GPS(GPSMacro: String): String;
Var
	Temp: String;
Begin
	Temp :=	GPSMacro;
	FGPSInfo.GPSLock.Enter;
	Try
		If Pos('%LAT%', GPSMacro) > 0 Then
			Temp := StringReplace(Temp, '%LAT%', FGPSInfo.Latitude, [RfIgnoreCase]);
		If Pos('%LON%', GPSMacro) > 0 Then
			Temp := StringReplace(Temp, '%LON%', FGPSInfo.Longtitude, [RfIgnoreCase]);
		If Pos('%ALT%', GPSMacro) > 0 Then
			Temp := StringReplace(Temp, '%ALT%', FGPSInfo.Altitude, [RfIgnoreCase]);
		If Pos('%DIR%', GPSMacro) > 0 Then
			Temp := StringReplace(Temp, '%DIR%', FGPSInfo.Direction, [RfIgnoreCase]);
		If Pos('%SPD%', GPSMacro) > 0 Then
			Temp := StringReplace(Temp, '%SPD%', FGPSInfo.Speed, [RfIgnoreCase]);
	Finally
		FGPSInfo.GPSLock.Leave;
	End;
	Exit(Temp);
End;

Function TGPSThread.PseudoMacro2GPS(GPSMacro: String): String;
Var
	Temp: String;
Begin
	Temp := GPSMacro;
	If Pos('%LAT%', GPSMacro) > 0 Then
	Begin
		If Length(FGPSInfo.North) < Length(FGPSInfo.South) Then
			Temp := StringReplace(Temp, '%LAT%', FGPSInfo.South + '888' + #$a1 + #$e3 + '88' + #$27 + '88.888"', [RfIgnoreCase])
		Else
			Temp := StringReplace(Temp, '%LAT%', FGPSInfo.North + '888' + #$a1 + #$e3 + '88' + #$27 + '88.888"', [RfIgnoreCase]);
	End;
	If Pos('%LON%', GPSMacro) > 0 Then
	Begin
		If Length(FGPSInfo.West) < Length(FGPSInfo.East) Then
			Temp := StringReplace(Temp, '%LON%', FGPSInfo.East + '888' + #$a1 + #$e3 + '88' + #$27 + '88.888"', [RfIgnoreCase])
		Else
			Temp := StringReplace(Temp, '%LON%', FGPSInfo.West + '888' + #$a1 + #$e3 + '88' + #$27 + '88.888"', [RfIgnoreCase]);
	End;
	If Pos('%ALT%', GPSMacro) > 0 Then
	Begin
		If Length(FGPSInfo.KM) < Length(FGPSInfo.M) Then
			Temp := StringReplace(Temp, '%ALT%', '8888.88' + FGPSInfo.M, [RfIgnoreCase])
		Else
			Temp := StringReplace(Temp, '%ALT%', '8888.88' + FGPSInfo.KM, [RfIgnoreCase]);
	End;
	If Pos('%DIR%', GPSMacro) > 0 Then
		Temp :=
			StringReplace(Temp, '%DIR%', '888' + #$a1 + #$e3 + '88' + #$27 + '88.888"', [RfIgnoreCase]);
	If Pos('%SPD%', GPSMacro) > 0 Then
	Begin
		If Length(FGPSInfo.KMH) < Length(FGPSInfo.MS) Then
			Temp := StringReplace(Temp, '%SPD%', '999' + FGPSInfo.MS, [RfIgnoreCase])
		Else
			Temp := StringReplace(Temp, '%SPD%', '999' + FGPSInfo.KMH, [RfIgnoreCase]);
	End;
	Exit(Temp);
End;

Procedure TGPSThread.SetKM(KMStr: String);
Begin
	FGPSInfo.SetKM(KMStr);
End;

Procedure TGPSThread.SetM(MStr: String);
Begin
	FGPSInfo.SetM(MStr);
End;

Procedure TGPSThread.SetSouth(NSStr: String);
Begin
	FGPSInfo.SetSouth(NSStr);
End;

Procedure TGPSThread.SetEast(WEStr: String);
Begin
	FGPSInfo.SetEast(WEStr);
End;

Procedure TGPSThread.SetNorth(NSStr: String);
Begin
	FGPSInfo.SetNorth(NSStr);
End;

Procedure TGPSThread.SetWest(WEStr: String);
Begin
	FGPSInfo.SetWest(WEStr);
End;

Procedure TGPSThread.SetKMH(KMHStr: String);
Begin
	FGPSInfo.SetKMH(KMHStr);
End;

Procedure TGPSThread.SetMS(MSStr: String);
Begin
	FGPSInfo.SetMS(MSStr);
End;

Procedure TGPSThread.SetTimeZone(dTimeZone: Double);
Begin
	FGPSInfo.TimeZone := dTimeZone;
End;

Initialization
Finalization
End.

